#ifndef B2D_GRAPHICSDEVICE_H
#define B2D_GRAPHICSDEVICE_H

#include "IGraphicsDevice.h"
#include "Texture.h"

NS_B2D_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief	Abstract graphics device.
/// 		Creates layer of abstraction between APIs
////////////////////////////////////////////////////////////////////////////////////////////////////
class B2D_API GraphicsDevice
	: public IGraphicsDevice
{
protected:
	RenderTarget* mActiveRenderTarget;

	TexturePtr mTextureSlots[TextureUnit::MAX];

	ShaderProgramPtr mActiveShaderProgram;

	BlendCoefficient	mBlendSrcCoeff;
	BlendCoefficient	mBlendDstCoeff;
	BlendFunction		mBlendFunction;

public:
	GraphicsDevice(void);
	virtual ~GraphicsDevice(void);

	RenderTarget* getActiveRenderTarget(void) const { return mActiveRenderTarget; }

	ShaderProgramPtr getActiveShaderProgram(void) const { return mActiveShaderProgram; }
	void setActiveShaderProgram(const ShaderProgramPtr& sp);
	void orderRenderTargets(void);

	size_t getActiveTextureCount(void) const;
	TexturePtr getTextureAt(TextureUnit::Unit slot) const;
	void clearTextures(void);

	void setBlending(BlendCoefficient src, BlendCoefficient dst, BlendFunction function);
	void getBlending(BlendCoefficient& src, BlendCoefficient& dst, BlendFunction& function) const;
	BlendCoefficient getBlendingSrcCoefficient(void) const { return mBlendSrcCoeff; }
	BlendCoefficient getBlendingDstCoefficient(void) const { return mBlendDstCoeff; }
	BlendFunction getBlendingFunction(void) const { return mBlendFunction; }

_internal:
	virtual void _setActiveRenderTarget(const RenderTarget& rt);

	
private:
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Bind the active shader.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual void setActiveShaderProgramImpl(void) = 0;


	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief	Implementation of setting the blending config.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	virtual void setBlendingImpl(void) = 0;
};

NS_B2D_END

#endif